// CancelCloseDlg.cpp : implementation file
//

#include "stdafx.h"
#include "LightspeedTraderAPIDemo.h"
#include "CancelCloseDlg.h"


// CancelCloseDlg dialog

IMPLEMENT_DYNAMIC(CancelCloseDlg, CDialog)

CancelCloseDlg::CancelCloseDlg(CWnd* pParent /*=NULL*/)
	: CModelessDialog(CancelCloseDlg::IDD, pParent)
	, m_CommandTypeCombo(CComboBox())
	, m_OrderPosCombo(CComboBox())
	, m_EquityCheck(CButton())
	, m_FutureCheck(CButton())
	, m_OptionCheck(CButton())
	, m_LongCheck(CButton())
	, m_ShortCheck(CButton())
	, m_FlatCheck(CButton())
	, m_DayCheck(CButton())
	, m_NonDayCheck(CButton())
	, m_BuyCheck(CButton())
	, m_SellCheck(CButton())
	, m_iCommandType(CANCEL_ALL_ORDERS)
	, account(NULL)
{

}

CancelCloseDlg::~CancelCloseDlg()
{
	if (account)
	{
		account->L_Detach(this);
		account = NULL;
	}
}

BOOL CancelCloseDlg::Create(CWnd *pParentWnd /*= CWnd::FromHandle(L_GetMainWnd())*/)
{
	return __super::Create(CancelCloseDlg::IDD, pParentWnd);
}

void CancelCloseDlg::DoDataExchange(CDataExchange* pDX)
{
	__super::DoDataExchange(pDX);

	DDX_Control(pDX, IDC_COMMANDTYPE_COMBO, m_CommandTypeCombo);
	DDX_Control(pDX, IDC_ORDERPOSCOMBO, m_OrderPosCombo);
	DDX_Control(pDX, IDC_EQUITYCHECK, m_EquityCheck);
	DDX_Control(pDX, IDC_FUTURECHECK, m_FutureCheck);
	DDX_Control(pDX, IDC_OPTIONCHECK, m_OptionCheck);
	DDX_Control(pDX, IDC_LONGCHECK, m_LongCheck);
	DDX_Control(pDX, IDC_SHORTCHECK, m_ShortCheck);
	DDX_Control(pDX, IDC_FLATCHECK, m_FlatCheck);
	DDX_Control(pDX, IDC_DAYCHECK, m_DayCheck);
	DDX_Control(pDX, IDC_NONDAYCHECK, m_NonDayCheck);
	DDX_Control(pDX, IDC_BUYCHECK, m_BuyCheck);
	DDX_Control(pDX, IDC_SELLCHECK, m_SellCheck);
}

BOOL CancelCloseDlg::OnInitDialog()
{
	__super::OnInitDialog();

	m_CommandTypeCombo.InsertString(CANCEL_ORDER, "Cancel Order");
	m_CommandTypeCombo.InsertString(CANCEL_ALL_ORDERS, "Cancel All Orders");
	m_CommandTypeCombo.InsertString(CANCEL_POSITION_ORDERS, "Cancel Position Orders");
	m_CommandTypeCombo.InsertString(CLOSE_ALL_POSITIONS, "Close All Positions");
	m_CommandTypeCombo.SetCurSel(m_iCommandType);

	m_EquityCheck.SetCheck(TRUE);
	m_FutureCheck.SetCheck(TRUE);
	m_OptionCheck.SetCheck(TRUE);
	m_LongCheck.SetCheck(TRUE);
	m_ShortCheck.SetCheck(TRUE);
	m_FlatCheck.SetCheck(TRUE);
	m_DayCheck.SetCheck(TRUE);
	m_NonDayCheck.SetCheck(TRUE);
	m_BuyCheck.SetCheck(TRUE);
	m_SellCheck.SetCheck(TRUE);

	account = L_GetAccount();
	account->L_Attach(this);

	return TRUE;
}

void CancelCloseDlg::UpdateEnabledControls()
{
	BOOL securityFlags = FALSE;
	BOOL positionFlags = FALSE;
	BOOL dayFlags = FALSE;
	BOOL sideFlags = FALSE;

	switch (m_iCommandType)
	{
	case CANCEL_ORDER:
		securityFlags = FALSE;
		positionFlags = FALSE;
		dayFlags = FALSE;
		sideFlags = FALSE;
		break;
	case CANCEL_ALL_ORDERS:
		securityFlags = TRUE;
		positionFlags = TRUE;
		dayFlags = TRUE;
		sideFlags = TRUE;
		break;
	case CANCEL_POSITION_ORDERS:
		securityFlags = FALSE;
		positionFlags = FALSE;
		dayFlags = TRUE;
		sideFlags = TRUE;
		break;
	case CLOSE_ALL_POSITIONS:
		securityFlags = TRUE;
		positionFlags = TRUE;
		dayFlags = FALSE;
		sideFlags = FALSE;
		break;
	}

	m_EquityCheck.EnableWindow(securityFlags);
	m_FutureCheck.EnableWindow(securityFlags);
	m_OptionCheck.EnableWindow(securityFlags);

	m_LongCheck.EnableWindow(positionFlags);
	m_ShortCheck.EnableWindow(positionFlags);
	m_FlatCheck.EnableWindow(positionFlags);

	m_DayCheck.EnableWindow(dayFlags);
	m_NonDayCheck.EnableWindow(dayFlags);

	m_BuyCheck.EnableWindow(sideFlags);
	m_SellCheck.EnableWindow(sideFlags);
}

void CancelCloseDlg::UpdateOrderPosCombo()
{
	while (m_OrderPosCombo.GetCount() > 0)
	{
		m_OrderPosCombo.DeleteString(0);
	}

	BOOL enableOrderPosCombo = FALSE;

	switch (m_iCommandType)
	{
	case CANCEL_ORDER:
		{
			CString text;

			for (order_iterator it(account->active_orders_begin()), itend(account->active_orders_end());
				it != itend; ++it)
			{
				text.Format("%d", (*it)->L_OrderId());
				m_OrderPosCombo.AddString(text);
			}
			m_OrderPosCombo.SetCurSel(0);
			enableOrderPosCombo = TRUE;
		}
		break;
	case CANCEL_POSITION_ORDERS:
		{
			CString text;

			for (position_iterator it(account->positions_begin()), itend(account->positions_end());
				it != itend; ++it)
			{
				text = (*it)->L_Symbol();
				m_OrderPosCombo.AddString(text);
			}
			m_OrderPosCombo.SetCurSel(0);
			enableOrderPosCombo = TRUE;
		}
		break;
	case CANCEL_ALL_ORDERS:
	case CLOSE_ALL_POSITIONS:
		enableOrderPosCombo = FALSE;
		break;
	}

	m_OrderPosCombo.EnableWindow(enableOrderPosCombo);
}

void CancelCloseDlg::HandleMessage(L_Message const *pMsg)
{
	switch (pMsg->L_Type())
	{
	case ::L_MsgOrderChange::id:
		UpdateOrderPosCombo();
		break;
	}
}

BEGIN_MESSAGE_MAP(CancelCloseDlg, CModelessDialog)
	ON_CBN_SELCHANGE(IDC_COMMANDTYPE_COMBO, OnCbnSelchangeCommandTypeCombo)
	ON_BN_CLICKED(IDC_EXECUTE_BUTTON, OnBnClickedExecute)
END_MESSAGE_MAP()

// CancelCloseDlg message handlers

void CancelCloseDlg::OnCbnSelchangeCommandTypeCombo()
{
	m_iCommandType = m_CommandTypeCombo.GetCurSel();

	UpdateEnabledControls();
	UpdateOrderPosCombo();
}

void CancelCloseDlg::OnBnClickedExecute()
{
	long dayFlags = L_DayFlag::NONE;
	long sideFlags = L_SideFlag::NONE;
	long securityFlags = L_SecFlag::NONE;
	long posFlags = L_PosFlag::NONE;

	dayFlags |= (m_DayCheck.GetCheck() ? L_DayFlag::DAY : 0);
	dayFlags |= (m_NonDayCheck.GetCheck() ? L_DayFlag::NONDAY : 0);

	sideFlags |= (m_BuyCheck.GetCheck() ? L_SideFlag::BUY : 0);
	sideFlags |= (m_SellCheck.GetCheck() ? L_SideFlag::SELL : 0);

	securityFlags |= (m_EquityCheck.GetCheck() ? L_SecFlag::EQUITY : 0);
	securityFlags |= (m_FutureCheck.GetCheck() ? L_SecFlag::FUTURE : 0);
	securityFlags |= (m_OptionCheck.GetCheck() ? L_SecFlag::OPTION : 0);

	posFlags |= (m_LongCheck.GetCheck() ? L_PosFlag::LONG : 0);
	posFlags |= (m_ShortCheck.GetCheck() ? L_PosFlag::SHORT : 0);
	posFlags |= (m_FlatCheck.GetCheck() ? L_PosFlag::FLAT : 0);

	switch(m_iCommandType)
	{
	case CANCEL_ORDER:
		{
			CString text;
			m_OrderPosCombo.GetLBText(m_OrderPosCombo.GetCurSel(), text);
			
			L_Order *order = account->L_FindOrderByOrderId(atol(text.GetBuffer()));
			if (order)
			{
				account->L_CancelOrder(order);
				order = NULL;
			}
		}
		break;
	case CANCEL_ALL_ORDERS:
		{
			account->L_CancelAllOrders(dayFlags, sideFlags, securityFlags, posFlags);
		}
		break;
	case CANCEL_POSITION_ORDERS:
		{
			CString text;
			m_OrderPosCombo.GetLBText(m_OrderPosCombo.GetCurSel(), text);

			L_Position *position = account->L_FindPosition(text.GetBuffer());
			if (position)
			{
				account->L_CancelPositionOrders(position, dayFlags, sideFlags);
				position = NULL;
			}
		}
		break;
	case CLOSE_ALL_POSITIONS:
		{
			account->L_CloseAllPositions(securityFlags, posFlags);
		}
		break;
	}
}